package com.littleHan.brushQuestions.configs;

import com.littleHan.brushQuestions.shiro.MyCredentialsMatcher;
import com.littleHan.brushQuestions.shiro.ShiroRealm;
import com.littleHan.brushQuestions.shiro.JwtFilter;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shiro配置类
 */
@Configuration
public class ShiroConfig {

    //注入自定义的Realm
    @Autowired
    private ShiroRealm shiroRealm;

    //注入自定义的密码管理器
    @Autowired
    private MyCredentialsMatcher myCredentialsMatcher;

    //DefaultWeSecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(){
        DefaultWebSecurityManager webSecurityManager=new DefaultWebSecurityManager();

        //关联自定义realm对象
        webSecurityManager.setRealm(shiroRealm);
        //管理自定义密码管理器
        shiroRealm.setCredentialsMatcher(myCredentialsMatcher);
        return webSecurityManager;
    }

    /**
     * ShiroFilterFactoryBean
     * 获取shiro过滤器
     * 主要配置需要拦截的路径
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager,JwtFilter jwtFilter){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();

        //关联DefaultWeSecurityManager 安全管理器对象
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        Map<String, Filter> filterMap=new HashMap<>();
        //管理过滤器
        shiroFilterFactoryBean.setFilters(filterMap);
        filterMap.put("jwt",jwtFilter);

        /*
            添加shiro的内置过滤器
            用于添加需要拦截的路径,并设置拦截级别
            拦截级别：，
              anon :无需认证就可以访问
              authc：必须认证了才能访问,
              user： 必须拥有 remeberMe（记住我）功能才能访问
              perms：拥有对某个资源的权限才能访问
              roles： 拥有某个角色才能访问
         */
        Map<String,String> interceptMap=new LinkedHashMap<>();

        //例如 拦截 修改个人资料 功能，设置为需要登录认证才能访问
        //interceptMap.put("/user/add","authc");

        //此处设置放行路径
        //interceptMap.put("/user/*","anon");
        interceptMap.put("/swagger-ui.html**","anon");
        interceptMap.put("/v2api-docs","anon");
        interceptMap.put("/swagger-resources/**","anon");

        interceptMap.put("/**","jwt");
        //使用通配符拦截所有请求
        //interceptMap.put("/**","authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(interceptMap);
        //拦截后会跳转到/login/toIndex
        shiroFilterFactoryBean.setLoginUrl("/login/toIndex");

        return shiroFilterFactoryBean;
    }

    @Bean
    public JwtFilter getJwtFilter(){
        return new JwtFilter();
    }

    // 开启注解代理
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    //创建 realm 对象，需要自定义类继承 AuthorizingRealm抽象类，并实现其抽象方法
    @Bean
    public ShiroRealm getDhiroRealm(){
        return new ShiroRealm();
    }



}
